package cn.com.zsw.gblog.modules.gblog.service.impl;

import cn.com.zsw.gblog.modules.gblog.dto.PostsPageDTO;
import cn.com.zsw.gblog.modules.gblog.dto.PostsSaveDTO;
import cn.com.zsw.gblog.modules.gblog.entity.GbCategoryEntity;
import cn.com.zsw.gblog.modules.gblog.entity.GbPostsEntity;
import cn.com.zsw.gblog.modules.gblog.mapper.GbCategoryMapper;
import cn.com.zsw.gblog.modules.gblog.mapper.GbPostsMapper;
import cn.com.zsw.gblog.modules.gblog.service.GbCategoryService;
import cn.com.zsw.gblog.modules.gblog.service.GbPostsService;
import cn.com.zsw.gblog.utils.DozerBeanUtils;
import cn.com.zsw.gblog.utils.PageUtils;
import cn.com.zsw.gblog.utils.SummaryUtils;
import cn.com.zsw.gblog.vo.PageRes;
import cn.com.zsw.gblog.modules.gblog.vo.PostListVo;
import cn.com.zsw.gblog.modules.gblog.vo.PostVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (GbPosts)表服务实现类
 *
 * @author shiwangzhou
 * @since 2020-06-22 11:29:45
 */
@Service("gbPostsService")
@CacheConfig(cacheNames = "postCache", cacheManager = "redisCacheManager")
public class GbPostsServiceImpl extends ServiceImpl<GbPostsMapper,
        GbPostsEntity> implements GbPostsService {
    @Resource
    SummaryUtils summaryUtils;
    @Resource
    private GbPostsMapper postsDao;
    @Resource
    private GbCategoryMapper categoryMapper;
    @Resource
    private GbCategoryService categoryService;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    @Cacheable(key = "#id")
    public PostVo view(String id) {
        //20201020 去掉后端markdown转html 由前端利用编辑器自动装解析
        GbPostsEntity gbPostsEntity = this.postsDao.selectById(id);
        Assert.notNull(gbPostsEntity, "查不到相关博客");
        PostVo postVo = new PostVo();
        BeanUtils.copyProperties(gbPostsEntity, postVo, "category");
        List<String> list = JSON.parseArray(gbPostsEntity.getCategory(), String.class);
        postVo.setCategory(list);
        return postVo;
    }

    @CacheEvict(key = "#id")
    @Override
    public PostsSaveDTO edit(String id) {
        GbPostsEntity gbPostsEntity = this.postsDao.selectById(id);
        Assert.notNull(gbPostsEntity, "查不到相关博客");
        PostsSaveDTO postsSaveDTO = new PostsSaveDTO();
        BeanUtils.copyProperties(gbPostsEntity, postsSaveDTO, "category");
        postsSaveDTO.setId(String.valueOf(gbPostsEntity.getId()));
        List<String> list = JSON.parseArray(gbPostsEntity.getCategory(), String.class);
        postsSaveDTO.setCategory(list);
        return postsSaveDTO;

    }

    /**
     * @param postsPageDTO
     * @Author: shiwangZhou
     * @Description:
     * @Date: 2020-06-22 14:06
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<cn.com.zsw.gblog.entity.GbPosts>
     * @Param postsPageDTO
     */
    @Override
    @Transactional(isolation = Isolation.DEFAULT)
    public PageRes<PostListVo> selectListPage(PostsPageDTO postsPageDTO) {
        Page<GbPostsEntity> page = new Page<>(postsPageDTO.getPageNum(), postsPageDTO.getPageSize());
        LambdaQueryWrapper<GbPostsEntity> wrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(postsPageDTO.getCategory())) {
            wrapper.like(GbPostsEntity::getCategory, postsPageDTO.getCategory());
        }
        if (StringUtils.isNotBlank(postsPageDTO.getSearchWords())) {
            wrapper.and(gbPostsLambdaQueryWrapper -> gbPostsLambdaQueryWrapper.like(GbPostsEntity::getTitle, postsPageDTO.getSearchWords())
                    .or().like(GbPostsEntity::getContent, postsPageDTO.getSearchWords()).or().like(GbPostsEntity::getSummary, postsPageDTO.getSearchWords()));

        }
        //判断是否登陆，如果登陆了的话，可以查询出编辑中状态的数据。未登录只可以查询出已发布的状态。
        boolean authenticated = SecurityContextHolder.getContext().getAuthentication().isAuthenticated();
        if (!authenticated) {
            wrapper.eq(GbPostsEntity::getStatus, 1);
        }
        wrapper.orderByDesc(GbPostsEntity::getIsTop);
        wrapper.orderByDesc(GbPostsEntity::getIsHot);
        wrapper.orderByDesc(GbPostsEntity::getPublishTime);
        Page<GbPostsEntity> gbPostsEntityPage = postsDao.selectPage(page, wrapper);
        List<PostListVo> collect = gbPostsEntityPage.getRecords()
                .stream().map(gbPostsEntity -> DozerBeanUtils.copy(gbPostsEntity, PostListVo.class)).collect(Collectors.toList());
        return PageUtils.buildResponse(page, collect);

    }

    /**
     * @param postsSaveDTO 博客数据
     * @Author: shiwangZhou
     * @Description: 发布博客
     * @Date: 2020-07-03 14:51
     * @Return void
     * @Param postsSaveDTO
     */
    @CacheEvict(key = "#postsSaveDTO.id")
    @Override
    public void savePost(PostsSaveDTO postsSaveDTO) {
        GbPostsEntity postDb = postsDao.selectById(postsSaveDTO.getId());
        GbPostsEntity postsEntity = DozerBeanUtils.copy(postsSaveDTO, GbPostsEntity.class);
        //更新
        //如果分类不存在则新增
        for (String s : postsSaveDTO.getCategory()) {
            int count = categoryService.count(Wrappers.<GbCategoryEntity>lambdaQuery().eq(GbCategoryEntity::getTitle, s));
            if (count < 1) {
                categoryService.add(s);
            }
        }
        postsEntity.setCategory(JSON.toJSONString(postsSaveDTO.getCategory()));
        //从content中生成摘要
        postsEntity.setSummary(summaryUtils.SummaryMeanstdTxt(postsEntity.getContent()));
        if (postDb != null) {
            postsEntity.setUpdateTime(new Date());
            postsDao.updateById(postsEntity);
            return;
        }
        postsEntity.setId(null);
        postsEntity.setUpdateTime(new Date());
        postsEntity.setCreateTime(new Date());
        postsEntity.setIsHot(0);
        postsEntity.setIsTop(0);
        postsEntity.setViewsCount(0);
        postsEntity.setCommentsCount(0);
        postsEntity.setPublishTime(1 == postsSaveDTO.getStatus()?postsEntity.getPublishTime():new Date());
        postsDao.insert(postsEntity);
    }
}